/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { IncrementalTask } from '../../../external/task/incremental-task.js';
import { BasicFileSnapshot } from '../core/filesystem-snapshot.js';
import { TaskSnapshot } from '../core/task-snapshot.js';
import { DefaultFilesystemSnapshotGenerator } from '../generator/default-filesystem-snapshot-generator.js';
import { DefaultTaskSnapshotGenerator } from '../generator/default-task-snapshot-generator.js';
import { FileSystemSnapshotGenerator } from '../generator/filesystem-snapshot-generator.js';
import { TaskSnapshotGenerator } from '../generator/task-snapshot-generator.js';
import { FsOptions } from '../util/file-set.js';

/**
 * Snapshot generator 外部统一入口单例类
 *
 * @since 2022/9/1
 */
export class SnapshotGeneratorService {
  private static _instance: SnapshotGeneratorService | null = null;
  private defaultFileSystemSnapshotGenerator: FileSystemSnapshotGenerator;
  private taskGenerator: TaskSnapshotGenerator;

  private constructor() {
    this.taskGenerator = new DefaultTaskSnapshotGenerator();
    this.defaultFileSystemSnapshotGenerator = new DefaultFilesystemSnapshotGenerator();
  }

  static getInstance(): SnapshotGeneratorService {
    if (!SnapshotGeneratorService._instance) {
      SnapshotGeneratorService._instance = new SnapshotGeneratorService();
    }
    return SnapshotGeneratorService._instance;
  }

  generateTaskSnapshot(task: IncrementalTask, generator?: TaskSnapshotGenerator): TaskSnapshot {
    if (generator) {
      return generator.snapshot(task);
    }
    return this.taskGenerator.snapshot(task);
  }

  /**
   * generateFileSystemSnapshot
   *
   * @param filepath file or directory path
   * @param options FsOptions for filter file
   * @param fileSystemSnapshotGenerator generator
   */
  generateFileSystemSnapshot(filepath: string, options?: FsOptions, fileSystemSnapshotGenerator?: FileSystemSnapshotGenerator): BasicFileSnapshot {
    if (fileSystemSnapshotGenerator) {
      return fileSystemSnapshotGenerator.snapshot(filepath, options);
    }
    return this.defaultFileSystemSnapshotGenerator.snapshot(filepath, options);
  }

  loadTaskSnapshotFromJson(jsonStr: string): TaskSnapshot {
    return this.taskGenerator.loadSnapshotFromJson(jsonStr);
  }

  loadTaskSnapshotCacheFromJson(text: string): Map<string, TaskSnapshot> {
    return this.taskGenerator.loadSnapshotCacheFromJson(text);
  }

  serializeTaskSnapshotCacheToJson(collection: Map<string, TaskSnapshot>): string {
    return this.taskGenerator.serializeSnapshotCacheToJson(collection);
  }

  /**
   * json string 转 FileSystem snapshot
   *
   * @param jsonStr
   */
  loadFileSystemSnapshotFromJson(jsonStr: string): BasicFileSnapshot | undefined {
    return this.defaultFileSystemSnapshotGenerator.loadSnapshotFromJson(jsonStr);
  }

  /**
   * json string 转 Map<string, BasicFileSnapshot>
   *
   * @param jsonStr
   */
  loadFileSystemSnapshotCacheFromJson(jsonStr: string): Map<string, BasicFileSnapshot> | undefined {
    return this.defaultFileSystemSnapshotGenerator.loadSnapshotCacheFromJson(jsonStr);
  }

  /**
   * serialize map of  BasicFileSnapshot to json string
   *
   * @param map
   */
  serializeFileSystemSnapshotToJson(map: Map<string, BasicFileSnapshot>): string {
    return this.defaultFileSystemSnapshotGenerator.serializeSnapshotToJson(map);
  }
}
